/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

// THIS FILE IS GENERATED BY ZAP
// This file is generated from clusters-shared-Structs.h.zapt

#pragma once

#include <app/data-model/DecodableList.h>
#include <app/data-model/List.h>
#include <app/data-model/Nullable.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/Optional.h>
#include <lib/core/TLV.h>
#include <lib/support/BitMask.h>

#include <clusters/shared/Enums.h>

#include <cstdint>

namespace chip
{
namespace app
{
	namespace Clusters
	{

		// Structs shared across multiple clusters.
		namespace detail
		{
			namespace Structs
			{

				namespace ModeTagStruct
				{
					enum class Fields : uint8_t {
						kMfgCode = 0,
						kValue = 1,
					};

					struct Type {
					public:
						Optional<chip::VendorId> mfgCode;
						uint16_t value = static_cast<uint16_t>(0);

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace ModeTagStruct
				namespace ModeOptionStruct
				{
					enum class Fields : uint8_t {
						kLabel = 0,
						kMode = 1,
						kModeTags = 2,
					};

					struct Type {
					public:
						chip::CharSpan label;
						uint8_t mode = static_cast<uint8_t>(0);
						DataModel::List<const Structs::ModeTagStruct::Type> modeTags;

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					struct DecodableType {
					public:
						chip::CharSpan label;
						uint8_t mode = static_cast<uint8_t>(0);
						DataModel::DecodableList<Structs::ModeTagStruct::DecodableType> modeTags;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;
					};

				} // namespace ModeOptionStruct
				namespace MeasurementAccuracyRangeStruct
				{
					enum class Fields : uint8_t {
						kRangeMin = 0,
						kRangeMax = 1,
						kPercentMax = 2,
						kPercentMin = 3,
						kPercentTypical = 4,
						kFixedMax = 5,
						kFixedMin = 6,
						kFixedTypical = 7,
					};

					struct Type {
					public:
						int64_t rangeMin = static_cast<int64_t>(0);
						int64_t rangeMax = static_cast<int64_t>(0);
						Optional<chip::Percent100ths> percentMax;
						Optional<chip::Percent100ths> percentMin;
						Optional<chip::Percent100ths> percentTypical;
						Optional<uint64_t> fixedMax;
						Optional<uint64_t> fixedMin;
						Optional<uint64_t> fixedTypical;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace MeasurementAccuracyRangeStruct
				namespace MeasurementAccuracyStruct
				{
					enum class Fields : uint8_t {
						kMeasurementType = 0,
						kMeasured = 1,
						kMinMeasuredValue = 2,
						kMaxMeasuredValue = 3,
						kAccuracyRanges = 4,
					};

					struct Type {
					public:
						MeasurementTypeEnum measurementType =
							static_cast<MeasurementTypeEnum>(0);
						bool measured = static_cast<bool>(0);
						int64_t minMeasuredValue = static_cast<int64_t>(0);
						int64_t maxMeasuredValue = static_cast<int64_t>(0);
						DataModel::List<const Structs::MeasurementAccuracyRangeStruct::Type>
							accuracyRanges;

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					struct DecodableType {
					public:
						MeasurementTypeEnum measurementType =
							static_cast<MeasurementTypeEnum>(0);
						bool measured = static_cast<bool>(0);
						int64_t minMeasuredValue = static_cast<int64_t>(0);
						int64_t maxMeasuredValue = static_cast<int64_t>(0);
						DataModel::DecodableList<
							Structs::MeasurementAccuracyRangeStruct::DecodableType>
							accuracyRanges;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;
					};

				} // namespace MeasurementAccuracyStruct
				namespace ApplicationStruct
				{
					enum class Fields : uint8_t {
						kCatalogVendorID = 0,
						kApplicationID = 1,
					};

					struct Type {
					public:
						uint16_t catalogVendorID = static_cast<uint16_t>(0);
						chip::CharSpan applicationID;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace ApplicationStruct
				namespace ErrorStateStruct
				{
					enum class Fields : uint8_t {
						kErrorStateID = 0,
						kErrorStateLabel = 1,
						kErrorStateDetails = 2,
					};

					struct Type {
					public:
						uint8_t errorStateID = static_cast<uint8_t>(0);
						Optional<chip::CharSpan> errorStateLabel;
						Optional<chip::CharSpan> errorStateDetails;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace ErrorStateStruct
				namespace LabelStruct
				{
					enum class Fields : uint8_t {
						kLabel = 0,
						kValue = 1,
					};

					struct Type {
					public:
						chip::CharSpan label;
						chip::CharSpan value;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace LabelStruct
				namespace OperationalStateStruct
				{
					enum class Fields : uint8_t {
						kOperationalStateID = 0,
						kOperationalStateLabel = 1,
					};

					struct Type {
					public:
						uint8_t operationalStateID = static_cast<uint8_t>(0);
						Optional<chip::CharSpan> operationalStateLabel;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace OperationalStateStruct
			} // namespace Structs
		} // namespace detail

		// Global structs.
		namespace Globals
		{
			namespace Structs
			{

				namespace CurrencyStruct
				{
					enum class Fields : uint8_t {
						kCurrency = 0,
						kDecimalPoints = 1,
					};

					struct Type {
					public:
						uint16_t currency = static_cast<uint16_t>(0);
						uint8_t decimalPoints = static_cast<uint8_t>(0);

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace CurrencyStruct

				namespace PriceStruct
				{
					enum class Fields : uint8_t {
						kAmount = 0,
						kCurrency = 1,
					};

					struct Type {
					public:
						int64_t amount = static_cast<int64_t>(0);
						Globals::Structs::CurrencyStruct::Type currency;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace PriceStruct

				namespace MeasurementAccuracyRangeStruct
				{
					enum class Fields : uint8_t {
						kRangeMin = 0,
						kRangeMax = 1,
						kPercentMax = 2,
						kPercentMin = 3,
						kPercentTypical = 4,
						kFixedMax = 5,
						kFixedMin = 6,
						kFixedTypical = 7,
					};

					struct Type {
					public:
						int64_t rangeMin = static_cast<int64_t>(0);
						int64_t rangeMax = static_cast<int64_t>(0);
						Optional<chip::Percent100ths> percentMax;
						Optional<chip::Percent100ths> percentMin;
						Optional<chip::Percent100ths> percentTypical;
						Optional<uint64_t> fixedMax;
						Optional<uint64_t> fixedMin;
						Optional<uint64_t> fixedTypical;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace MeasurementAccuracyRangeStruct

				namespace MeasurementAccuracyStruct
				{
					enum class Fields : uint8_t {
						kMeasurementType = 0,
						kMeasured = 1,
						kMinMeasuredValue = 2,
						kMaxMeasuredValue = 3,
						kAccuracyRanges = 4,
					};

					struct Type {
					public:
						Globals::MeasurementTypeEnum measurementType =
							static_cast<Globals::MeasurementTypeEnum>(0);
						bool measured = static_cast<bool>(0);
						int64_t minMeasuredValue = static_cast<int64_t>(0);
						int64_t maxMeasuredValue = static_cast<int64_t>(0);
						DataModel::List<
							const Globals::Structs::MeasurementAccuracyRangeStruct::Type>
							accuracyRanges;

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					struct DecodableType {
					public:
						Globals::MeasurementTypeEnum measurementType =
							static_cast<Globals::MeasurementTypeEnum>(0);
						bool measured = static_cast<bool>(0);
						int64_t minMeasuredValue = static_cast<int64_t>(0);
						int64_t maxMeasuredValue = static_cast<int64_t>(0);
						DataModel::DecodableList<
							Globals::Structs::MeasurementAccuracyRangeStruct::DecodableType>
							accuracyRanges;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;
					};

				} // namespace MeasurementAccuracyStruct

				namespace AtomicAttributeStatusStruct
				{
					enum class Fields : uint8_t {
						kAttributeID = 0,
						kStatusCode = 1,
					};

					struct Type {
					public:
						chip::AttributeId attributeID = static_cast<chip::AttributeId>(0);
						uint8_t statusCode = static_cast<uint8_t>(0);

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace AtomicAttributeStatusStruct

				namespace ICECandidateStruct
				{
					enum class Fields : uint8_t {
						kCandidate = 0,
						kSDPMid = 1,
						kSDPMLineIndex = 2,
					};

					struct Type {
					public:
						chip::CharSpan candidate;
						DataModel::Nullable<chip::CharSpan> SDPMid;
						DataModel::Nullable<uint16_t> SDPMLineIndex;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace ICECandidateStruct

				namespace ICEServerStruct
				{
					enum class Fields : uint8_t {
						kURLs = 0,
						kUsername = 1,
						kCredential = 2,
						kCaid = 3,
					};

					struct Type {
					public:
						DataModel::List<const chip::CharSpan> URLs;
						Optional<chip::CharSpan> username;
						Optional<chip::CharSpan> credential;
						Optional<uint16_t> caid;

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					struct DecodableType {
					public:
						DataModel::DecodableList<chip::CharSpan> URLs;
						Optional<chip::CharSpan> username;
						Optional<chip::CharSpan> credential;
						Optional<uint16_t> caid;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;
					};

				} // namespace ICEServerStruct

				namespace LocationDescriptorStruct
				{
					enum class Fields : uint8_t {
						kLocationName = 0,
						kFloorNumber = 1,
						kAreaType = 2,
					};

					struct Type {
					public:
						chip::CharSpan locationName;
						DataModel::Nullable<int16_t> floorNumber;
						DataModel::Nullable<Globals::AreaTypeTag> areaType;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace LocationDescriptorStruct

				namespace PowerThresholdStruct
				{
					enum class Fields : uint8_t {
						kPowerThreshold = 0,
						kApparentPowerThreshold = 1,
						kPowerThresholdSource = 2,
					};

					struct Type {
					public:
						Optional<int64_t> powerThreshold;
						Optional<int64_t> apparentPowerThreshold;
						DataModel::Nullable<Globals::PowerThresholdSourceEnum>
							powerThresholdSource;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace PowerThresholdStruct

				namespace TestGlobalStruct
				{
					enum class Fields : uint8_t {
						kName = 0,
						kMyBitmap = 1,
						kMyEnum = 2,
					};

					struct Type {
					public:
						chip::CharSpan name;
						DataModel::Nullable<chip::BitMask<Globals::TestGlobalBitmap>> myBitmap;
						Optional<DataModel::Nullable<Globals::TestGlobalEnum>> myEnum;

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace TestGlobalStruct

				namespace ViewportStruct
				{
					enum class Fields : uint8_t {
						kX1 = 0,
						kY1 = 1,
						kX2 = 2,
						kY2 = 3,
					};

					struct Type {
					public:
						uint16_t x1 = static_cast<uint16_t>(0);
						uint16_t y1 = static_cast<uint16_t>(0);
						uint16_t x2 = static_cast<uint16_t>(0);
						uint16_t y2 = static_cast<uint16_t>(0);

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = false;

						CHIP_ERROR Encode(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
					};

					using DecodableType = Type;

				} // namespace ViewportStruct

				namespace WebRTCSessionStruct
				{
					enum class Fields : uint8_t {
						kId = 0,
						kPeerNodeID = 1,
						kPeerEndpointID = 2,
						kStreamUsage = 3,
						kVideoStreamID = 4,
						kAudioStreamID = 5,
						kMetadataEnabled = 6,
						kFabricIndex = 254,
					};

					struct Type {
					public:
						uint16_t id = static_cast<uint16_t>(0);
						chip::NodeId peerNodeID = static_cast<chip::NodeId>(0);
						chip::EndpointId peerEndpointID = static_cast<chip::EndpointId>(0);
						Globals::StreamUsageEnum streamUsage =
							static_cast<Globals::StreamUsageEnum>(0);
						DataModel::Nullable<uint16_t> videoStreamID;
						DataModel::Nullable<uint16_t> audioStreamID;
						Optional<bool> metadataEnabled;
						chip::FabricIndex fabricIndex = static_cast<chip::FabricIndex>(0);

						CHIP_ERROR Decode(TLV::TLVReader &reader);

						static constexpr bool kIsFabricScoped = true;

						auto GetFabricIndex() const { return fabricIndex; }

						void SetFabricIndex(chip::FabricIndex fabricIndex_)
						{
							fabricIndex = fabricIndex_;
						}

						CHIP_ERROR EncodeForWrite(TLV::TLVWriter &aWriter, TLV::Tag aTag) const;
						CHIP_ERROR EncodeForRead(TLV::TLVWriter &aWriter, TLV::Tag aTag,
									 FabricIndex aAccessingFabricIndex) const;

					private:
						CHIP_ERROR
						DoEncode(TLV::TLVWriter &aWriter, TLV::Tag aTag,
							 const Optional<FabricIndex> &aAccessingFabricIndex) const;
					};

					using DecodableType = Type;

				} // namespace WebRTCSessionStruct

			} // namespace Structs
		} // namespace Globals
	} // namespace Clusters
} // namespace app
} // namespace chip
